from brownie import *
import brownie

ALL = {"token": [], "controller": [], "vault": [], "strategy": []}

TOKEN = [Token]
CONTROLLER = [Controller]
VAULTS = [yVault, yWETH, yDelegatedVault]
STRATEGIES = [
    StrategyCreamYFI,
    StrategyCurveBTCVoterProxy,
    StrategyCurveBUSDVoterProxy,
    StrategyCurveEURVoterProxy,
    StrategyCurveYVoterProxy,
    StrategyCurve3CrvVoterProxy,
    StrategyDAICurve,
    StrategyDForceUSDC,
    StrategyDForceUSDT,
    # StrategyMKRVaultDAIDelegate,  # 合约部署出错
    StrategyTUSDCurve,
    StrategyVaultUSDC,
]

ENV = "development"

if config["networks"]["default"] in ["test", "naturelab"]:
    ENV = "live"


def main():
    # 如果是在线环境，先清除所有节点托管的账户，从助记词恢复账户
    if ENV == "live":
        accounts.clear()
        accounts.from_mnemonic(
            "season turtle oblige language winner purpose call engine thunder pepper cactus base",
            10,
        )

    # 设置账户
    tok = accounts[0]
    default = accounts[1]
    rewards = accounts[2]  # 奖励地址
    gov = accounts[3]  # 管理员地址，一般用管理员地址部署合约
    controller = accounts[4]  # 控制器地址

    ##############################  1.部署token
    token = tok.deploy(Token, nonce=0)
    ALL["token"].append(token.address)

    ##############################  2.部署控制器相关的合约

    # 指定nonce,可以保证合约地址一样
    controller = gov.deploy(Controller, rewards, nonce=0)
    ALL["controller"].append(controller.address)

    ##############################  3.部署金库合约

    nonce_list = [1, 2, 3]

    N = len(VAULTS)

    # 部署金库合约
    def vault_deployment(gov, token, controller, index):

        Vault = VAULTS[index]
        nonce = nonce_list[index]

        # 指定nonce,可以保证合约地址一样
        vault = gov.deploy(Vault, token, controller, nonce=nonce)

        ALL["vault"].append(vault.address)

        assert vault.governance() == gov
        assert vault.controller() == controller
        assert vault.token() == token

        assert vault.name() == "yearn " + token.name()
        assert vault.symbol() == "y" + token.symbol()
        assert vault.decimals() == token.decimals()

    for index in range(N):
        vault_deployment(gov, token, controller, index)

    ##############################  4.部署策略合约

    N = len(STRATEGIES)
    nonce_list = range(4, 15)

    def strategy_deployment(gov, controller, index):
        # gov 管理员地址，部署合约
        # controller 控制器地址

        Strategy = STRATEGIES[index]
        nonce = nonce_list[index]

        print("gov address:", gov)
        print("controller address", controller)
        print("Strategy", Strategy._name)

        strategy = gov.deploy(Strategy, controller)
        ALL["strategy"].append(strategy.address)

        assert strategy.governance() == gov
        assert strategy.controller() == controller
        assert strategy.getName() == Strategy._name

    for index in range(N):
        strategy_deployment(gov, controller, index)

    print(ALL)

    #############################    5.设置controller参数

    def controller_setParams(accounts, gov, rewards, getter, setter, val):
        if not val:
            # 如果变量没有值，则表示采用默认的备用账户地址default
            val = default

        # 加载已经部署的合约
        # controller = Controller.at("0xf34169b02747E45DA4AB7844d38D95f05060b60d")

        # getattr(controller, setter)(val, {"from": default})
        getattr(controller, setter)(val, {"from": gov})

        assert getattr(controller, getter)() == val

    # Controller合约中，setSplit，setOneSplit，setGovernance三个操作都要求使用管理者账户操作
    params = [
        ("split", "setSplit", 1000),
        ("onesplit", "setOneSplit", None),
        # ("governance", "setGovernance", None),
    ]

    for getter, setter, val in params:
        controller_setParams(accounts, gov, rewards, getter, setter, val)

    #############################    6.设置vault参数
    # 金库合约设置参数
    def vault_setParams(accounts, gov, token, controller, getter, setter, val, index):
        if not val:
            val = default

        # 加载已经部署的合约
        contract_address = ALL["vault"][index]
        vault = VAULTS[index].at(contract_address)

        if not hasattr(vault, getter):
            return

        getattr(vault, setter)(val, {"from": gov})
        assert getattr(vault, getter)() == val

    params = [
        ("min", "setMin", 9000),
        ("healthFactor", "setHealthFactor", 100),
        ("controller", "setController", None),
        # ("governance", "setGovernance", None),
    ]

    N = len(VAULTS)

    for index in range(N):
        for getter, setter, val in params:
            vault_setParams(
                accounts, gov, token, controller, getter, setter, val, index
            )

    #############################    7.设置strategy参数

    def strategy_setParams(accounts, gov, controller, getter, setter, val, index):
        if not val:
            val = default

        Strategy = STRATEGIES[index]
        strategy = Strategy.at(ALL["strategy"][index])

        if not hasattr(strategy, getter):
            return

        getattr(strategy, setter)(val, {"from": gov})
        assert getattr(strategy, getter)() == val

    params = [
        # ("governance", "setGovernance", None),
        ("controller", "setController", None),
        ("strategist", "setStrategist", None),
        ("fee", "setFee", 100),
        ("withdrawalFee", "setWithdrawalFee", 100),
        ("performanceFee", "setPerformanceFee", 1000),
    ]

    N = len(STRATEGIES)
    for index in range(N):
        for getter, setter, val in params:
            strategy_setParams(accounts, gov, controller, getter, setter, val, index)

    print("部署结果:\n", ALL)
